home *** CD-ROM | disk | FTP | other *** search
- #ifndef EXEC_EXECBASE_H
- #include <exec/execbase.h>
- #endif
-
- #ifndef EXEC_ALERTS_H
- #include <exec/alerts.h>
- #endif
-
- #ifndef RESOURCES_MISC_H
- #include <resources/misc.h>
- #endif
-
- #ifndef HARDWARE_CIA_H
- #include <hardware/cia.h>
- #endif
-
- #ifndef DOS_FILEHANDLER_H
- #include <dos/filehandler.h>
- #endif
-
- #ifndef CLIB_EXEC_PROTOS_H
- #include <clib/exec_protos.h>
- #endif
-
- #ifndef CLIB_DOS_PROTOS_H
- #include <clib/dos_protos.h>
- #endif
-
- #ifndef CLIB_MISC_PROTOS_H
- #include <clib/misc_protos.h>
- #endif
-
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/misc_pragmas.h>
-
- /***********************************************/
-
- struct Interrupt *CIAA_AddICRVector(long, struct Interrupt *);
- void CIAA_RemICRVector(long, struct Interrupt *);
- WORD CIAA_AbleICR(long);
- WORD CIAA_SetICR(long);
-
- #pragma libcall CIAABase CIAA_AddICRVector 6 9002
- #pragma libcall CIAABase CIAA_RemICRVector C 9002
- #pragma libcall CIAABase CIAA_AbleICR 12 001
- #pragma libcall CIAABase CIAA_SetICR 18 001
-
- extern struct CIA volatile __far ciaa;
- extern struct CIA volatile __far ciab;
-
- /***********************************************/
-
- void DummyInterrupt(void) {} /* Just in case... */
-
- /***********************************************/
-
- void __saveds FastPAR(void)
-
- {
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase;
- struct DosPacket *Packet;
- struct DeviceNode *DeviceNode;
- APTR MiscBase;
- APTR CIAABase;
- struct Process *MyProcess;
- struct Interrupt CIAAInterrupt;
- WORD OldMask;
-
- SysBase=(struct ExecBase *)*(ULONG *)4;
- if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37L)))
- {
- Alert(AT_DeadEnd | AG_OpenLib | AO_DOSLib);
- }
- MyProcess=(struct Process *)(SysBase->ThisTask);
-
- Packet=WaitPkt();
- DeviceNode=BADDR(Packet->dp_Arg3);
- DeviceNode->dn_Task=&MyProcess->pr_MsgPort;
- ReplyPkt(Packet,DOSTRUE,0L);
-
- MiscBase=NULL;
- CIAAInterrupt.is_Node.ln_Type=NT_UNKNOWN;
- CIAAInterrupt.is_Node.ln_Name="FastPAR";
- CIAAInterrupt.is_Code=DummyInterrupt;
- while (TRUE)
- {
- Packet=WaitPkt();
- switch(Packet->dp_Type)
- {
- case ACTION_FINDINPUT:
- case ACTION_FINDOUTPUT:
- case ACTION_FINDUPDATE: if (MiscBase)
- {
- ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_IN_USE);
- break;
- }
- if (!(MiscBase=OpenResource("misc.resource")))
- {
- Alert(AT_DeadEnd | AG_OpenRes | AO_MiscRsrc);
- }
- if (AllocMiscResource(MR_PARALLELPORT,"FastPAR"))
- {
- MiscBase=NULL;
- ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_IN_USE);
- break;
- }
- if (AllocMiscResource(MR_PARALLELBITS,"FastPAR"))
- {
- FreeMiscResource(MR_PARALLELPORT);
- MiscBase=NULL;
- ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_IN_USE);
- break;
- }
- if (!(CIAABase=OpenResource("ciaa.resource")))
- {
- Alert(AT_DeadEnd | AG_OpenRes | AO_CIARsrc);
- }
- Disable();
- if (CIAA_AddICRVector(CIAICRB_FLG,&CIAAInterrupt))
- {
- Enable();
- MiscBase=NULL;
- ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_IN_USE);
- break;
- }
- CIAA_SetICR(CIAICRF_FLG);
- OldMask=CIAA_AbleICR(CIAICRF_FLG) & CIAICRF_FLG;
- Enable();
- ciaa.ciaddrb=0xff;
- ciab.ciaddra&=~(CIAF_PRTRSEL | CIAF_PRTRPOUT | CIAF_PRTRBUSY);
- ReplyPkt(Packet,DOSTRUE,0L);
- break;
-
- case ACTION_WRITE: {
- long Count;
- char *CharPointer;
- BYTE OldTaskPri;
-
- CharPointer=(char *)Packet->dp_Arg2;
- OldTaskPri=SetTaskPri(MyProcess,-5);
- for (Count=0; Count<Packet->dp_Arg3; Count++)
- {
- while (ciab.ciapra & CIAF_PRTRBUSY) ;
- ciaa.ciaprb=*CharPointer++;
- while (!(CIAA_SetICR(CIAICRF_FLG) & CIAICRF_FLG)) ;
- }
- SetTaskPri(MyProcess,OldTaskPri);
- ReplyPkt(Packet,Count,0L);
- }
- break;
-
- case ACTION_END: CIAA_SetICR(CIAICRF_SETCLR | OldMask);
- CIAA_AbleICR(CIAICRF_SETCLR | OldMask);
- CIAA_RemICRVector(CIAICRB_FLG,&CIAAInterrupt);
- FreeMiscResource(MR_PARALLELBITS);
- FreeMiscResource(MR_PARALLELPORT);
- MiscBase=NULL;
- ReplyPkt(Packet,DOSTRUE,0L);
- break;
-
- case ACTION_DIE: if (!MiscBase)
- {
- Forbid();
- if (IsMsgPortEmpty(&MyProcess->pr_MsgPort))
- {
- ReplyPkt(Packet,DOSTRUE,0L);
- UnLoadSeg(DeviceNode->dn_SegList);
- DeviceNode->dn_SegList=NULL;
- DeviceNode->dn_Task=NULL;
- CloseLibrary((struct Library *)DOSBase);
- return;
- }
- Permit();
- }
- ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_IN_USE);
- break;
-
- default: ReplyPkt(Packet,DOSFALSE,ERROR_ACTION_NOT_KNOWN);
- break;
- }
- }
- }
-